using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Business.WaitingOutboundManagement.Dto;
using Business.Models;
using Microsoft.AspNetCore.Authorization;
using Business.Permissions;

namespace Business.WaitingOutboundManagement
{
    [Authorize(BusinessPermissions.WaitingOutbound.Default)]
    public class WaitingOutboundAppService : ApplicationService,IWaitingOutboundAppService
    {
        private const string FormName = "WaitingOutbound";
        private IRepository<WaitingOutbound, Guid> _repository;

        public WaitingOutboundAppService(
            IRepository<WaitingOutbound, Guid> repository
            )
        {
            _repository = repository;
        }
        #region 增删改查基础方法

        public async Task<WaitingOutboundDto> Get(Guid id)
        {
            var data = await _repository.GetAsync(id);
            var dto = ObjectMapper.Map<WaitingOutbound, WaitingOutboundDto>(data);
            return dto;
        }

        public async Task<PagedResultDto<WaitingOutboundDto>> GetAll(GetWaitingOutboundInputDto input)
        {
            // 设定筛选条件
            DateTime? startDate = null;
            DateTime? endDate = null;

            var query = (await _repository.GetQueryableAsync()).WhereIf(!string.IsNullOrWhiteSpace(input.Filter), a => a.Buyer.Contains(input.Filter)).WhereIf(!string.IsNullOrWhiteSpace(input.OrderNumber) && input.OddNumber == "1", a => a.OrderNumber.Contains(input.OrderNumber)).WhereIf(!string.IsNullOrWhiteSpace(input.OrderNumber) && input.OddNumber == "2", a => a.ExternalOrderNumber.Contains(input.OrderNumber)).WhereIf(!string.IsNullOrWhiteSpace(input.OrderNumber) && input.OddNumber == "3", a => a.OnlineOrderNumber.Contains(input.OrderNumber)).WhereIf(!string.IsNullOrWhiteSpace(input.Buyer), a => a.Buyer.Contains(input.Buyer)).WhereIf(input.IsOrderNumber != null && input.IsOrderNumber == true, a => a.TrackingNumber != null).WhereIf(input.IsOrderNumber != null && input.IsOrderNumber == false, a => a.TrackingNumber == null).WhereIf(input.SelectedValues != null, a => input.SelectedValues.Contains(a.PlatformStore)).WhereIf(!string.IsNullOrWhiteSpace(input.Carrier), a => input.Carrier.Contains(a.Carrier)).WhereIf(!string.IsNullOrWhiteSpace(input.Phone), a => a.Phone.Contains(input.Phone)).WhereIf(!string.IsNullOrWhiteSpace(input.OutboundType), a => a.OutboundType == input.OutboundType); // 修改这里的查询条件，确保它能支持多个地址的情况

            // 获取用户输入的时间类型
            switch (input.SelectedTime)
            {
                case "仓库接单时间":
                    startDate = GetStartDate(input.SelectedRange);
                    endDate = GetEndDate(input.SelectedRange);
                    if (startDate.HasValue && endDate.HasValue)
                    {
                        query = query.Where(a => a.WarehouseOrderTime >= startDate && a.PaymentTime <= endDate);
                    }
                    break;
                case "下单时间":
                    // 这里可以设置下单时间的开始和结束日期
                    startDate = GetStartDate(input.SelectedRange);
                    endDate = GetEndDate(input.SelectedRange);
                    if (startDate.HasValue && endDate.HasValue)
                    {
                        query = query.Where(a => a.OrderTime >= startDate && a.PaymentTime <= endDate);
                    }
                    break;
                case "付款时间":
                    // 这里可以设置付款时间的开始和结束日期
                    startDate = GetStartDate(input.SelectedRange);
                    endDate = GetEndDate(input.SelectedRange);
                    if (startDate.HasValue && endDate.HasValue)
                    {
                        query = query.Where(a => a.PaymentTime >= startDate && a.PaymentTime <= endDate);
                    }

                    break;
                case "最晚发货时间":
                    startDate = GetStartDate(input.SelectedRange);
                    endDate = GetEndDate(input.SelectedRange);
                    // 添加筛选条件
                    if (startDate.HasValue && endDate.HasValue)
                    {
                        query = query.Where(a => a.LatestShipmentTime >= startDate && a.LatestShipmentTime <= endDate);
                    }
                    break;
            }

            // 处理PickingArea
            if (!string.IsNullOrWhiteSpace(input.PickingArea))
            {
                var address = input.PickingArea.Split(",");
                foreach (var addr in address)
                {
                    var trimmedAddress = addr.Trim();
                    if (!string.IsNullOrEmpty(trimmedAddress))
                    {   
                         query = query.Where(a => a.DetailedAddress.Contains(trimmedAddress));
                    }

                }
            }

            var totalCount = await query.CountAsync();
            var items = await query.OrderBy(input.Sorting ?? "Id")
                       .Skip(input.SkipCount)
                       .Take(input.MaxResultCount)
                       .ToListAsync();

            var dto = ObjectMapper.Map<List<WaitingOutbound>, List<WaitingOutboundDto>>(items);
            return new PagedResultDto<WaitingOutboundDto>(totalCount, dto);
        }

        private DateTime GetStartDate(string selectedRange)
        {
            return selectedRange switch
            {
                "today" => DateTime.Today,
                "7days" => DateTime.Today.AddDays(-7),
                "30days" => DateTime.Today.AddDays(-30),
                _ => DateTime.MinValue,
            };
        }

        private DateTime GetEndDate(string selectedRange)
        {
            return selectedRange switch
            {
                "today" => DateTime.Today.AddDays(1).AddTicks(-1),
                "7days" => DateTime.Today,
                "30days" => DateTime.Today,
                _ => DateTime.MaxValue,
            };
        }


        public async Task<WaitingOutboundDto> DataPost(CreateOrUpdateWaitingOutboundDto input)
        {
            WaitingOutbound result = null;
            if (!input.Id.HasValue)
            {
                input.Id = GuidGenerator.Create();
                result = await _repository.InsertAsync(ObjectMapper.Map<CreateOrUpdateWaitingOutboundDto, WaitingOutbound>(input));
            }
            else
            {
                var data = await _repository.GetAsync(input.Id.Value);
                result = await _repository.UpdateAsync(ObjectMapper.Map(input, data));
            }
            return ObjectMapper.Map<WaitingOutbound, WaitingOutboundDto>(result);
        }

        public async Task Delete(List<Guid> ids)
        {
            foreach (var item in ids)
            {
                await _repository.DeleteAsync(item);
            }

        }

     
        #endregion

    }
}